const io = require('socket.io')({})
const redisCfg = configure.get('redis')
const socketUtil = require('./socketUtil')
const redis = require('redis').createClient
const adapter = require('socket.io-redis')
const pub = redis(redisCfg)
const sub = redis(redisCfg)
const sysAppService = require('../../../service/dao/sys/sys_app')

const amqp_cfg = configure.get('amqp')
const im_suffix = amqp_cfg.im_suffix || ''

console.log('init socket.io ...')

exports.listen = async (server) => {
    await M('service_reg').updateMany({ im_suffix: im_suffix }, { $set: { client_ids: [] } })

    const io = require('socket.io')(server, {maxHttpBufferSize: 1e8, perMessageDeflate: false})

    io.adapter(adapter({ pubClient: pub, subClient: sub }))

    // 使用中间件验证jwt
    io.use((socket, next) => {
        let jwt = socket.handshake.headers['authorization'] || socket.handshake.headers['Authorization'] || socket.handshake.query.jwt || ''
        jwt = jwt.replace(/Bearer /i, '')

        sysAppService.check(jwt).then(payload => {
            socket.jwt = payload
            return next()
        }).catch(e => {
            return next(new Error(e.message))
        })
    })

    io.on('connection', async (socket) => {
        console.log(`${socket.id} connected ~~ `)

        socket.on('disconnect', async () => {
            let app_names = socket.jwt['app_name'].split('_')
            let user_id = socket.jwt['user_id']
            let _current_socket_type = app_names[1]

            if (app_names.length > 1) {
                // web端 离开 room
                if (_current_socket_type === 'web' && user_id) {
                    console.log(`${user_id} leave room: ${user_id}_web`)
                    socket.leave(`${user_id}_web`)
                }
            } else {
                await M('service_reg').updateOne({
                    app_key: socket.jwt.app_key,
                    im_suffix: im_suffix
                }, { $pull: { client_ids: socket.id } })

                let _svr = await dbUtil.getRow('service_reg', { app_key: socket.jwt.app_key, im_suffix: im_suffix })
                _svr.client_ids.map(async (_s, _i) => {
                    _i === 0 ?
                        await socketUtil.emitMessage(io, _s, socketUtil.messageBuilder(1000, { is_leader: true }), 'LeaderSelect')
                        :
                        await socketUtil.emitMessage(io, _s, socketUtil.messageBuilder(1000, { is_leader: false }), 'LeaderSelect')
                })
            }

            console.log(`${socket.id} disconnected ~~`)
            socket.disconnect(true)
            socket && delete io.sockets.sockets[socket.id]// 释放socket
            socket = null
        })

        // 处理socket初始化相关操作
        await socketUtil.initialize(io, socket, socket.jwt)
    })
}
